/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package iplayer;

import com.sun.javafx.functions.Function0;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javafx.async.RunnableFuture;

/**
 *
 * @author stephengalbraith
 */
public class AsyncGetIplayerOperation implements RunnableFuture {

    private String type;
    private String chanel;
    private String program;
    private Pattern pattern;
    private String get_iplayer;

    public static enum SearchCategory {

        TV, Radio, LiveTV, LiveRadio
    }
    private LateReturnable value;
    private Process process;

    public AsyncGetIplayerOperation(LateReturnable value, String get_iplayer, String type, String chanel, String program) {
        this.value = value;
        this.type = type;
        this.chanel = chanel;
        this.program = program;
        this.pattern = Pattern.compile("(\\d+):(.+),(.+)");
        this.get_iplayer = get_iplayer;

    }

    public void run() {
        try {
            this.process = Runtime.getRuntime().exec(new String[]{this.get_iplayer, "--long", "--type", type, "--channel", chanel, "--info", (program.equals("all") ? "" : program)});
            final InputStreamReader inputStreamReader = new InputStreamReader(this.process.getInputStream());
            BufferedReader buf = new BufferedReader(inputStreamReader);
            String line = "";
            Program currentProgram = null;
            while (line != null) {
                line = buf.readLine();
                if (line != null) {
                    final Matcher m = pattern.matcher(line);
                    if (m.matches()) {
                        if (null != currentProgram) {
                            this.setReturnValue(currentProgram);
                        }
                        currentProgram = new Program();

                    } else {
                        this.decodeLineInfo(currentProgram, line);
                    }

                }

            }
            if (null != currentProgram) {
                this.setReturnValue(currentProgram);
            }
            System.out.println("finished");
            buf.close();
            inputStreamReader.close();
            this.process.getInputStream().close();
        } catch (Exception e) {
            // never
            e.printStackTrace();
        }
    }

    public void kill() {
        if (null != this.process) {
            this.process.destroy();
        }
    }

    void setReturnValue(final Program input) {
        input.compressRawData();
        javafx.lang.FX.deferAction(new Function0<Void>() {

            public Void invoke() {
                AsyncGetIplayerOperation.this.value.setValue(input);
                return null;
            }
        });
    }

    private void decodeLineInfo(Program currentProgram, String line) {
        System.out.println(currentProgram + "extractinginfo->" + line);
        if (line.startsWith("longname:")) {
            currentProgram.name = line.substring(9).trim();
        } else if (line.startsWith("thumbnail:")) {
            currentProgram.thumbnailURL = line.substring(10).trim();
        } else if (line.startsWith("desc:")) {
            currentProgram.description = line.substring(5).trim();
        } else if (line.startsWith("pid:")) {
            currentProgram.pid = line.substring(4).trim();
        } else if (line.startsWith("modes:")) {
            System.out.println(currentProgram + "extracting modes from->" + line);

            String beforeDefaultDetect = line.substring(6).trim();
            if (beforeDefaultDetect.startsWith("default:")) {

                final String[] rawStrings = beforeDefaultDetect.substring(8).split(",");
                currentProgram.modes = new String[rawStrings.length];
                for (int i = 0; i < rawStrings.length; i++) {
                    currentProgram.modes[i] = rawStrings[i].trim();
                }
                if (beforeDefaultDetect.contains("flashnormal")) {
                    currentProgram.defaultMode = "flashnormal";
                } else {
                    currentProgram.defaultMode = currentProgram.modes[0].trim();
                }
                System.out.print("got default mode!!!" + currentProgram.defaultMode);
            }
        } else if (line.startsWith("modesizes:")) {
            System.out.println(currentProgram + "extracting modes from->" + line);
            String beforeDefaultDetect = line.substring(10).trim();
            if (beforeDefaultDetect.startsWith("default:")) {

                currentProgram.modeSizes = beforeDefaultDetect.substring(8).split(",");
                for (int i = 0; i < currentProgram.modeSizes.length; i++) {
                    currentProgram.modeSizes[i] = currentProgram.modeSizes[i].substring(currentProgram.modeSizes[i].indexOf("="));
                }
                 System.out.print("got default mode sizes!!!" + currentProgram.modeSizes);
            }
        } else if (line.startsWith("duration:")) {
            currentProgram.duration = line.substring(9).trim();
        } else if (line.startsWith("episode:")) {
            currentProgram.episode = line.substring(8).trim();
        } else if (line.startsWith("series:")) {
            currentProgram.series = line.substring(5).trim();
        }
    }
}
